/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.worlds;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import net.worlds.object.Box;
import org.jbox2d.common.Mat22;
import org.jbox2d.common.Vec2D;
import org.jbox2d.common.XForm;


public class WorldsBoxDef
{
    public Vec2D pos;
    public float angle;
    public Vec2D size;
    public Vec2D velocity;
    public XForm xf;
    public float angularVelocity;
    public int destroyedLevel;
    private LinkedHashMap<String, Object> properties;
    public WorldsBoxDef(Box b) throws WorldsException
    {
        pos = b.getPosition();
        angle = b.getBody().getAngle();
        size = b.getVec2DProp("Size");
        velocity = b.getVelocity();
        xf = b.getBody().getXForm();
        properties = b.getAllProperties();
    }
    public WorldsBoxDef()
    {

    }
    public Vec2D getLocalPoint(Vec2D worldPoint)
    {
        return XForm.mulTrans(xf, worldPoint);
    }
    public Vec2D getWorldPoint(Vec2D localPoint){
            return XForm.mul(xf, localPoint);
    }
    public Object getProp(String k)
    {
        return properties.get(k);
    }
    public ArrayList<WorldsBoxDef> subdivide(ArrayList<WorldsBoxDef> parts, Vec2D pos, Vec2D origPoint, int level, float ratio, int explosionID) throws WorldsException
    {
        if(level > 5 || size.x < 0.25 || size.y < 0.25)
        {
            if(!parts.contains(this))
                parts.add(this);
            return parts;
        }
        Vec2D local = getLocalPoint(pos);
        boolean isY = Math.abs(Math.abs(local.y) - size.y / 2) < 0.1;
        boolean isX = Math.abs(Math.abs(local.x) - size.x / 2) < 0.1;
        boolean sub0 = false, sub1 = false;
        Vec2D center0 = null, center1 = null;
        Vec2D next = null;
        float p0X = 0, p1X = 0, p0Y = 0, p1Y = 0;
        if(isX && isY)
        {
            isX = Math.random() < 0.5;
            isY = !isX;
        }
        if(isY && !isX)
        {
            next = getWorldPoint(new Vec2D((float) local.x, 0));
            p0X = size.x/2 - Math.abs(local.x);
            p1X = size.x - p0X;
            p0Y = size.y;
            p1Y = size.y;
            if(local.x > 0)
               center0 = new Vec2D(local.x/2 + size.x/4, 0);
            else
               center0 = new Vec2D(size.x/2 - size.x/4, 0);
            if(local.x > 0)
               center1 = new Vec2D(local.x/2 - size.x/4, 0);
            else
               center1 = new Vec2D(local.x/2 + size.x/4, 0);
        }
        else if(isX && !isY)
        {
            next = new Vec2D(getWorldPoint(new Vec2D(0, (float) local.y)));
            p0X = size.x;
            p1X = size.x;
            p0Y = size.y/2 - Math.abs(local.y);
            p1Y = size.y - p0Y;
            if(local.y > 0)
               center0 = new Vec2D(0, local.y/2 + size.y/4);
            else
               center0 = new Vec2D(0, local.y/2 - size.y/4);
            if(local.y > 0)
               center1 = new Vec2D(0, local.y/2 - size.y/4);
            else
               center1 = new Vec2D(0, local.y/2 + size.y/4);
        }
        if(p0X != 0)
        {
            Vec2D worldCenter1 = getWorldPoint(center0);
            Vec2D worldCenter2 = getWorldPoint(center1);
            float d0 = Math.abs(new Vec2D(worldCenter1.x - origPoint.x, worldCenter1.y - origPoint.y).length());
            float d1 = Math.abs(new Vec2D(worldCenter2.x - origPoint.x, worldCenter2.y - origPoint.y).length());
            if(Math.abs(d0 - d1) < 0.1 || level == 0)
            {
                sub0 = true;
                sub1 = true;
            }
            else if(d0 > d1)
            {
                sub0 = false;
                sub1 = true;
            }
            else if(d1 > d0)
            {
                sub0 = true;
                sub1 = false;
            }
            WorldsBoxDef b = null;
            WorldsBoxDef b2 = null;
            boolean do0 = p0X > 0.5 && p0Y > 0.5;
            boolean do1 = p1X > 0.5 && p1Y > 0.5;
            sub0 = sub0 && do0;
            sub1 = sub1 && do1;
            {
                /*b = new Box();
                b.setProp("Position", worldCenter1, true);
                b.setProp("Size", new Vec2D(p0X, p0Y ), true);
                b.setProp("Layer", getProp("Layer"), true);
                b.setProp("Rotation", getProp("Rotation"), true);
                b.setProp("MaxForce", getProp("MaxForce"), true);
                b.setProp("Color", getProp("Color"), true);
                b.setProp("ShowBorder", getProp("ShowBorder"), true);
                b.setProp("Parent", Main.getActiveWorld().getService("World"), true);
                b.getBody().setLinearVelocity(getBody().getLinearVelocity());
                b.getBody().setAngularVelocity(getBody().getAngularVelocity());
                b.getBody().m_explosionID = explosionID;
                b.destroyedLevel = destroyedLevel + 1;*/
                b = new WorldsBoxDef();
                XForm bxf = new XForm();
                bxf.position = worldCenter1;
                bxf.R = new Mat22((float)angle);
                b.xf = bxf;
                b.pos = worldCenter1;
                b.angle = angle;
                b.size = new Vec2D(p0X, p0Y);
                b.properties = properties;
                b.velocity = velocity;
                b.angularVelocity = angularVelocity;
                int s = parts.size();
                //if(sub0)
                //    b.subdivide(parts, next, origPoint, level + 1, ratio, explosionID);
                sub0 = parts.size() > s;
            }
            {
                /*b2 = new Box();
                b2.setProp("Position", worldCenter2, true);
                b2.setProp("Size", new Vec2D(p1X, p1Y), true);
                b2.setProp("Layer", getProp("Layer"), true);
                b2.setProp("Rotation", getProp("Rotation"), true);
                b2.setProp("MaxForce", getProp("MaxForce"), true);
                b2.setProp("Color", getProp("Color"), true);
                b2.setProp("ShowBorder", getProp("ShowBorder"), true);
                b2.setProp("Parent", Main.getActiveWorld().getService("World"), true);
                b2.getBody().setLinearVelocity(getBody().getLinearVelocity());
                b2.getBody().setAngularVelocity(getBody().getAngularVelocity());
                b2.destroyedLevel = destroyedLevel + 1;
                b2.getBody().m_explosionID = explosionID;*/
                b2 = new WorldsBoxDef();
                XForm bxf = new XForm();
                bxf.position = worldCenter2;
                bxf.R = new Mat22((float)angle);
                b2.xf = bxf;
                b2.pos = worldCenter2;
                b2.angle = angle;
                b2.size = new Vec2D(p1X, p1Y);
                b2.properties = properties;
                b2.velocity = velocity;
                b2.angularVelocity = angularVelocity;
                /*if(texture != null)
                {
                    float worldStartX = center0.x - p0X/2;
                    float worldStartY = center0.y + p0Y/2;
                    float cornerX = pos.x - size.x/2;
                    float cornerY = pos.y + size.y/2;
                    int imageX = (int) (worldStartX - cornerX) * 8;
                    int imageY = (int) (worldStartY - cornerY) * 8;
                    int imageW = (int) (p0X * 8);
                    int imageH = (int) (p0Y * 8);
                    b.texture = texture.getSubimage(imageX, imageY, imageW, imageH);
                }*/
                int s = parts.size();
                //if(sub1)
                //    b2.subdivide(parts, next, origPoint, level + 1, ratio, explosionID);
                sub1 = parts.size() > s;
            }
            if(do0 || do1)
                parts.remove(this);
            if(!parts.contains(b) && !sub0 && do0)
                parts.add(b);
            if(!parts.contains(b2) && !sub1 && do1)
                parts.add(b2);
            return parts;
        }
        return parts;
    }
}
